package com.maxd.controller.statistics;

import com.maxd.error.Result;
import com.maxd.error.ResultUtil;
import com.maxd.model.UserInfo;
import com.maxd.model.invitationTotal;
import com.maxd.respository.cash.CashJpaRepository;
import com.maxd.respository.cash.CashRepository;
import com.maxd.respository.common.CommonRepository;
import com.maxd.respository.jifen.JiFenRepository;
import com.maxd.respository.pay.PayDetailsRepository;
import com.maxd.respository.selfOrder.OrdersRepository;
import com.maxd.respository.userinfo.UserJpaRepository;
import com.maxd.respository.userinfo.UserRepository;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.*;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@Api(value = "数据统计中心", tags = {"数据统计中心"})
@RequestMapping(value = "/statistics")
public class StatisticsController {
    @Autowired
    private UserJpaRepository userJpaRepository;
    @Autowired
    private CashJpaRepository cashJpaRepository;
    @Autowired
    private CashRepository cashRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private JiFenRepository jiFenRepository;
    @Autowired
    private CommonRepository commonRepository;
    @Autowired
    private OrdersRepository ordersRepository;
    @Autowired
    private PayDetailsRepository payDetailsRepository;


    @RequestMapping(value = "/getCountByTime", method = RequestMethod.GET)
    @ApiOperation("根据日期统计团长人数列表")
    @ResponseBody
    public Result totalInvitation(@RequestParam String time) {
        List<Long> invitationList = userRepository.findInvitationList(time);
        List<invitationTotal> list = new ArrayList<>();
        for (Long l : invitationList) {
            Long countByTime = userRepository.getCountByTime(String.valueOf(l), time);
            invitationTotal invitationTotal = new invitationTotal();
            invitationTotal.setGrade(String.valueOf(l));
            invitationTotal.setUserName(String.valueOf(l));
            invitationTotal.setMoney(Math.round(Float.parseFloat(String.valueOf(countByTime))));
            list.add(invitationTotal);
        }
        List<invitationTotal> sortDesList = list.stream().sorted(Comparator.comparingInt(invitationTotal::getMoney).reversed()).collect(Collectors.toList());
        sortDesList.stream().forEach(s -> System.out.println(s.getMoney()));
        return ResultUtil.success(sortDesList);
    }

    @RequestMapping(value = "/totalJiFen", method = RequestMethod.GET)
    @ApiOperation("管理平台统计 积分")
    @ResponseBody
    public Result totalJiFen(@RequestParam String time) {
        List<String> jiFenList = jiFenRepository.findJiFenList(time);
        List<invitationTotal> list = new ArrayList<>();
        for (String l : jiFenList) {
            UserInfo userInfo = userJpaRepository.findById(Long.valueOf(l)).orElse(null);
            Long countByTime = jiFenRepository.countJiFen(time, l);//统计积分数量
            String s = jiFenRepository.sumJiFen(time, l);//统计积分额度
            invitationTotal invitationTotal = new invitationTotal();
            invitationTotal.setGrade(String.valueOf(countByTime));
            assert userInfo != null;
            String number = "";
            if (userInfo != null && StringUtils.isNotEmpty(userInfo.getRelationId())){
                number = userInfo.getRelationId();
            }
            invitationTotal.setUserName(number);
            if (s != null) {
                invitationTotal.setMoney(Math.round(Float.parseFloat(s)));
            } else {
                invitationTotal.setMoney(0);
            }
            list.add(invitationTotal);
        }
        List<invitationTotal> sortDesList = list.stream().sorted(Comparator.comparingInt(invitationTotal::getMoney).reversed()).collect(Collectors.toList());
        sortDesList.stream().forEach(s -> System.out.println(s.getMoney()));
        return ResultUtil.success(sortDesList);
    }


    @RequestMapping(value = "/totalRelation", method = RequestMethod.GET)
    @ApiOperation("管理平台获取所有团长 统计邀请人数")
    @ResponseBody
    public Result totalRelation() {
        List<UserInfo> allByRelationIdNotNullOrderByIdDesc = userJpaRepository.findAllByRelationIdNotNullOrderByIdDesc();
        List<invitationTotal> list = new ArrayList<>();
        for (UserInfo userInfo : allByRelationIdNotNullOrderByIdDesc) {
            synchronized (SingleById.getById(String.valueOf(userInfo.getRelationId()))) {
                invitationTotal invitationTotal = new invitationTotal();
                invitationTotal.setGrade(userInfo.getRelationId());
                invitationTotal.setTime(userInfo.getCreateAt());
                invitationTotal.setUserName(userInfo.getPhone());
                invitationTotal.setMoney(Math.round(Float.parseFloat(userRepository.getCount(userInfo.getRelationId()))));
                list.add(invitationTotal);
            }
        }
        List<invitationTotal> sortDesList = list.stream().sorted(Comparator.comparingInt(invitationTotal::getMoney).reversed()).collect(Collectors.toList());
        sortDesList.stream().forEach(s -> System.out.println(s.getMoney()));
        return ResultUtil.success(sortDesList);
    }


    @RequestMapping(value = "/totalRelationCash", method = RequestMethod.GET)
    @ApiOperation("管理平台 累计会员提现统计")
    @ResponseBody
    public Result totalRelationCash() {
        List<Long> relationList = cashRepository.findRelationList();
        List<invitationTotal> list = new ArrayList<>();
        for (Long l : relationList) {
            synchronized (SingleById.getById(String.valueOf(l))) {
                UserInfo userInfo = userRepository.getUserByRelationId(String.valueOf(l));
                invitationTotal invitationTotal = new invitationTotal();
                invitationTotal.setGrade(userInfo.getRelationId());
                invitationTotal.setTime(userInfo.getCreateAt());
                invitationTotal.setUserName(userInfo.getPhone());
                invitationTotal.setMoney(Math.round(Float.parseFloat(cashRepository.countByRelationId(String.valueOf(l)))));
                list.add(invitationTotal);
            }
        }
        List<invitationTotal> sortDesList = list.stream().sorted(Comparator.comparingInt(invitationTotal::getMoney).reversed()).collect(Collectors.toList());
        sortDesList.stream().forEach(s -> System.out.println(s.getMoney()));
        return ResultUtil.success(sortDesList);
    }

    @ApiOperation("管理平台提现统计")
    @GetMapping("/getSumMoneyByTime")
    public Result getSumMoneyByTime(@RequestParam String time) {
        Long countNumberByTime = cashRepository.getCountNumberByTime(time);//提现笔数
        String sumMoneyByTime = cashRepository.getSumMoneyByTime(time);//累计提现金额
        Long notOutMoneyByTime = cashRepository.getNotOutMoneyByTime();//待转账用户
        Map<String, String> map = new HashMap<>();
        map.put("countNumberByTime", String.valueOf(countNumberByTime));
        map.put("sumMoneyByTime", sumMoneyByTime);
        map.put("notOutMoneyByTime", String.valueOf(notOutMoneyByTime));
        return ResultUtil.success(map);
    }

    @RequestMapping(value = "/getCashList/{page}/{size}", method = RequestMethod.GET)
    @ApiOperation("用户端轮播展示用户提现")
    @ResponseBody
    public Result getCashList(@PathVariable int page, @PathVariable int size) {
        Sort.Order order = new Sort.Order(Sort.Direction.DESC, "id");
        Pageable pageable = PageRequest.of(page, size, Sort.by(order));
        return ResultUtil.success(cashJpaRepository.findAll(pageable));
    }

    @RequestMapping(value = "/getCountNumberByTime", method = RequestMethod.GET)
    @ApiOperation("管理平台统计根据时间统计注册用户")
    @ResponseBody
    public Result getCountNumberByTime(@RequestParam String time) {
        return ResultUtil.success(userRepository.getCountNumberByTime(time));
    }

    @RequestMapping(value = "/getCountNumberByTimeByRelationId", method = RequestMethod.GET)
    @ApiOperation("管理平台统计根据时间统计注册会员")
    @ResponseBody
    public Result getCountNumberByTimeByRelationId(@RequestParam String time) {
        return ResultUtil.success(userRepository.getCountNumberByTimeByRelationId(time));
    }

    @RequestMapping(value = "/getCountNumberByTimeRAndRelationIdIsNull", method = RequestMethod.GET)
    @ApiOperation("管理平台统计普通用户 不是会员用户")
    @ResponseBody
    public Result getCountNumberByTimeRAndRelationIdIsNull(@RequestParam String time) {
        return ResultUtil.success(userRepository.getCountNumberByTimeRAndRelationIdIsNull(time));
    }

    @RequestMapping(value = "/getCountNumberByTimeByPhone", method = RequestMethod.GET)
    @ApiOperation("管理平台统计绑定手机号用户")
    @ResponseBody
    public Result getCountNumberByTimeByPhone(@RequestParam String time) {
        return ResultUtil.success(userRepository.getCountNumberByTimeByPhone(time));
    }

    @RequestMapping(value = "/getUserTotalByPhone", method = RequestMethod.GET)
    @ApiOperation("管理平台统计微信公众号用户")
    @ResponseBody
    public Result getCountNumberByTimeByWx(@RequestParam String time) {
        return ResultUtil.success(userRepository.getCountNumberByTimeByWx(time));
    }

    @RequestMapping(value = "/getCountNumberByTimeByMp", method = RequestMethod.GET)
    @ApiOperation("管理平台统计小程序用户")
    @ResponseBody
    public Result getCountNumberByTimeByMp(@RequestParam String time) {
        return ResultUtil.success(userRepository.getCountNumberByTimeByMp(time));
    }

    @RequestMapping(value = "/getCountUser", method = RequestMethod.GET)
    @ApiOperation("根据渠道时间统计用户")
    @ResponseBody
    public Result getCountUser(@RequestParam String time, @RequestParam String platform) {
        return ResultUtil.success(userRepository.getCountUser(time, platform));
    }

    @RequestMapping(value = "/getUserTotal", method = RequestMethod.GET)
    @ApiOperation("管理平台用户分析")
    @ResponseBody
    public Result getUserTotal(@RequestParam String time, @RequestParam String platform, @RequestParam int type) {
        return ResultUtil.success(queryFlows(platform, time, type));
    }

    @GetMapping("/getUserPlatformByTime")
    @ApiOperation("用户来源统计")
    @ResponseBody
    public Result getUserPlatformByTime(String time){
        int app = userRepository.getUserPlatformByTime(time, "app");
        int weixin = userRepository.getUserPlatformByTime(time, "weixin");
        int mp = userRepository.getUserPlatformByTime(time, "mp");
        Map<String,Integer> result=new HashMap<>();
        result.put("app",app);
        result.put("weixin",weixin);
        result.put("mp",mp);
        return ResultUtil.success(result);
    }


    private Long queryFlows(String platform, String createAt, int type) {
        // 构造自定义查询条件
        Specification<UserInfo> queryCondition = new Specification<UserInfo>() {
            @Override
            public Predicate toPredicate(Root<UserInfo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicateList = new ArrayList<>();
                if (!platform.equals("all")) {
                    predicateList.add(criteriaBuilder.equal(root.get("platform"), platform));
                }
                /*if (type != -1) {
                    predicateList.add(criteriaBuilder.equal(root.get("isRelation"), type));
                }*/
                if (type == 1) { //会员用户
                    predicateList.add(criteriaBuilder.isNotNull(root.get("relationId")));
                }else if ( type == 0){ //普通用户
                    predicateList.add(criteriaBuilder.isNull(root.get("relationId")));
                }
                if (createAt != null) {
                    predicateList.add(criteriaBuilder.like(root.get("createAt"), "%" + createAt + "%"));
                }
                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
            }
        };
        return userJpaRepository.count(queryCondition);
    }

    //非线程安全实现，需要修改
    static class SingleById {
        static Map<String, Object> map = new HashMap<>();

        static Object getById(String userId) {
            if (map.get(userId) != null) {
                return map.get(userId);
            } else {
                Object object = new Object();
                map.put(userId, object);
                return object;
            }
        }
    }

    @GetMapping("/payStatistics")
    @ApiOperation("充值统计")
    public Result payStatistics(String time){
        //总金额  微信  支付宝
        BigDecimal weiXinMoney = payDetailsRepository.selectPayMoneyStatistics(time, 1);
        BigDecimal zhiFuBaoMoney = payDetailsRepository.selectPayMoneyStatistics(time, 2);
        weiXinMoney =weiXinMoney.add(ordersRepository.selectOrdersPayWxSumMoney(time));
        zhiFuBaoMoney =zhiFuBaoMoney.add(ordersRepository.selectOrdersPayZfbSumMoney(time));
        Map<String,BigDecimal> result=new HashMap<>();
        result.put("weiXinMoney",weiXinMoney);
        result.put("zhiFuBaoMoney",zhiFuBaoMoney);
        result.put("money",weiXinMoney.add(zhiFuBaoMoney));
        return ResultUtil.success(result);
    }


}
